/***********************************************************************************************************
* TNA - The Network Auditor
* Copyright © 2012  Jeff Scaparra -- SPAWAR Systems Center LANT
*
* This file is a part of TNA.
************************************************************************************************************/
#include "commandLineParser.h"
#include "packetsniffer.h"
#include <iostream>
#include "stringUtils.h"
#include "helper.h"

void printHelp( );

namespace tna
{
  const std::string k_defaultInterface = "eth0";
  const std::string k_defaultConfFile = "/etc/tna.conf";
}

int main(int argc, char *argv[])
{
  PacketSniffer sniffer;

  std::string help = parser( argc, argv, "-h" );
  if( help.size() > 0 )
  {
    printHelp();
    return 0;
  }

  std::string interface = parser(argc, argv, "-i" );
  if( interface.size() > 0 )
  {
    sniffer.setDevice(interface);
  }
  else
  {
    sniffer.setDevice(tna::k_defaultInterface);
  }

  std::string confFile = parser( argc, argv, "-c" );
  if( confFile.size() > 0 )
  {
    sniffer.setConfFile( confFile );
  }
  else
  {
    sniffer.setConfFile( tna::k_defaultConfFile );
  }

  std::string v4Netblocks = parser( argc, argv, "-n4" );
  if( v4Netblocks.size() > 0 )
  {
    //set netblocks;
    std::vector< std::string > netblocks = split( v4Netblocks, ',' );
    for( uint i = 0; i < netblocks.size(); ++i )
    {
      std::vector< std::string > netblock = split( netblocks[i], '/' );
      if( netblock.size()  != 2 )
      {
        std::cerr << "Bad v4 Netblock Description" << std::endl;
        break;
      }
      else
      {
        IPv4Address network( netblock[0] );
        uint32_t mask = 0;
        uint16_t bits = ss_atoi<uint16_t>(netblock[1]);
        for( int k = 0; k < bits; ++k )
        {
          mask <<=1;
          mask |= 1;
        }
        IPv4Address netmask( mask );
        sniffer.tcpServicePortDiscoverer()->addV4Netblock(network, netmask);
      }
    }
  }

  std::string v6Netblocks = parser( argc, argv, "-n6" );
  if( v6Netblocks.size() > 0 )
  {
    //set netblocks;
    std::vector< std::string > netblocks = split( v6Netblocks, ',' );
    for( uint i = 0; i < netblocks.size(); ++i )
    {
      std::vector< std::string > netblock = split( netblocks[i], '/' );
      if( netblock.size()  != 2 )
      {
        std::cerr << "Bad v4 Netblock Description" << std::endl;
        break;
      }
      else
      {
        IPv6Address network( netblock[0] );
        std::vector< uint8_t > mask( IPv6Address::IPv6AddressSize );

        uint16_t bits = ss_atoi<uint16_t>(netblock[1]);
        for( int k = 0; k < bits; ++k )
        {
          int byte = k / 8;
          mask[byte] <<=1;
          mask[byte] |= 1;
        }
        IPv6Address netmask( mask );
        sniffer.tcpServicePortDiscoverer()->addV6Netblock(network,netmask);
      }
    }
  }

  sniffer.start();
}


void printHelp( )
{
  std::cerr << "TNA (C) 2011 Jeff Scaparra & Wesley Huang\n";
  std::cerr << "USAGE: \n";
  std::cerr << " -h   print help \n";
  std::cerr << " -i <interface> interface to listen on \n";
  std::cerr << " -c <configFile> config file to set options for auditing components \n";
  std::cerr << " -n4 <netblocks> specifies netblocks in a.b.c.d/z format comma seperated with no spaces \n";
  std::cerr << " -n6 <netblocks> specifies netblocks in ::/z format comma seperated with no spaces \n";
  std::cerr << std::endl;
}
